<?php
/**
 * CRMLite Config Controller
 *
 * @final
 * @package Crmlite_Module_Default
 * @version $Id: ConfigController.php 45 2007-09-04 10:07:53Z etng2004 $
 * @copyright 2006-2007 ETE.CN
 * @author Yi BO  <etng2004@gmail.com>
 * @license PHP Version 3.0 {@link http://www.php.net/license/3_0.txt}
 */
require_once dirname(__FILE__) . '/AdminBaseController.php';
final class Admin_ConfigController extends AdminBaseController
{
	public function init()
	{
		parent::init();
		$this->pushPoint('系统配置');
	}
	public function aclAction()
	{
		$Cache 			= Zend_Registry::get('cache');
		/* @var $Cache Zend_Cache_Core */
		$cache_id = 'acl';

		$ZACL = new Zend_Acl();
		$acls = $_POST['fields']['resource'];
		$roles = explode(" ", 'guest member staff admin');
		foreach ($roles as $role)
		{
			$ZACL->addRole(new Zend_Acl_Role($role));
		}

		foreach ($acls as $resource => $allowed_roles)
		{
			$allowed_roles = array_filter($allowed_roles, create_function('$s', 'return $s!="ALL";'));
			$ZACL->add(new Zend_Acl_Resource($resource));
			$ZACL->deny(null, $resource);
			$ZACL->allow($allowed_roles, $resource);
		}
		$Cache->save($ZACL, $cache_id);
		echo "Finish";
		exit();
	}
	public function indexAction()
	{
		$this->log('Config Index Called!');
		$modes = array('flat', 'tree');
		$mode = $this->_getParam('mode', reset($modes));
		in_array($mode, $modes) || $mode = reset($modes);
		$this->view->mode 		= $mode;
		$this->view->resources 	= $this->getResourceTree($mode);
		$this->view->roles 		= explode(" ", 'guest member staff admin');
	}
	function flatResourceTree($resources)
	{
		$new_res = array();
		foreach ($resources as $module=>$controllers)
		{
			foreach ($controllers as $controller=>$actions)
			{
				foreach ($actions as $action)
				{
					$new_res[] = $module . '_' . $controller . '_' . $action;
				}
			}
		}
		return $new_res;
	}
	/**
	 * Scan All Modules and Controllers for Privilieges
	 *
	 */
	function getResourceTree($mode = 'tree')
	{
		$Cache 			= Zend_Registry::get('cache');
		/* @var $Cache Zend_Cache_Core */
		$cache_id 		= 'ACL_RESOURCE_TREE' . $mode . md5('ACL_RESOURCE_TREE');
		if($resources 	= $Cache->get($cache_id))return $resources;
		/**
		 * 如果没有命中缓存，则重新生成
		 */
		$ControllerDirectories 	= $this->getFrontController()->getControllerDirectory();
		$DefaultModule			= $this->getFrontController()->getDefaultModule();
		$resources 				= array();
		foreach ($ControllerDirectories as $module => $dir)
		{
			$this->log("Module {$module} Located at {$dir}");
			$suffix = 'Controller.php';
			$dir .= DIRECTORY_SEPARATOR;

			foreach (glob($dir . '*' . $suffix ) as $ControllerFile)
			{
				$BaseName = substr($ControllerFile, strlen($dir), -strlen($suffix));
				$ControllerClass = $BaseName . 'Controller';
				if($module != $DefaultModule)
				{
					$ControllerClass = ucfirst($module) . '_' . $ControllerClass;
				}
				$this->log("Class {$ControllerClass} In file {$ControllerFile}");
				try {
					require_once $ControllerFile;
					if($methods = get_class_methods($ControllerClass))
					{
						$methods = array_filter($methods, array($this, 'isActionMethod'));
						array_walk($methods, array($this, 'getActionName'));
						$this->log("<h3>The Following Methods found:</h3><pre> " . var_export($methods, true) . "</pre> ");
						$resources[$module][$BaseName] = $methods;
					}
				}
				catch (Exception $e)
				{
					$this->log("Error:". $e->getMessage());
				}
			}
		}
		$this->log("<pre> " . var_export($resources, true) . "</pre> ");
		if($mode == 'flat')
		{
			$resources = $this->flatResourceTree($resources);
		}
		$Cache->save($resources, $cache_id);
		return $resources;
	}
	/**
	 * array_walk 回调函数，从类中的方法中提取 Action
	 *
	 * @param string $method	方法名称
	 */
	function getActionName(&$method)
	{
		if(preg_match('!(.+)Action$!i', $method, $match))
		{
			$method = $match[1];
		}
	}
	/**
	 * array_filter 回调函数， 判断方法名称是否合法的 Action 名称
	 *
	 * @param string $method	数组中的其中一个元素
	 * @return bool				如果为 false ,则会从数组中剔除该元素
	 */
	function isActionMethod($method)
	{
		return preg_match('!(.+)Action$!i', $method);
	}
}
